// HungTrung.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include <windows.h>
#include "HungTrung.h"
#include "../../game/GameCore/CGame.h"
#include <time.h>
#include "stdio.h"
#include "bass.h"
/////for get mac
/*
#include <Iphlpapi.h>
#include <Assert.h>
#pragma comment(lib, "iphlpapi.lib")

extern "C" void GetMACaddress(void){
	IP_ADAPTER_INFO AdapterInfo[16];			// Allocate information for up to 16 NICs
	DWORD dwBufLen = sizeof(AdapterInfo);		// Save the memory size of buffer

	DWORD dwStatus = GetAdaptersInfo(			// Call GetAdapterInfo
		AdapterInfo,							// [out] buffer to receive data
		&dwBufLen);								// [in] size of receive data buffer
	assert(dwStatus == ERROR_SUCCESS);			// Verify return value is valid, no buffer overflow

	PIP_ADAPTER_INFO pAdapterInfo = AdapterInfo;// Contains pointer to current adapter info
	do {
		printf("MAC Address: %02X-%02X-%02X-%02X-%02X-%02X\n", 
		pAdapterInfo->Address[0], pAdapterInfo->Address[1], pAdapterInfo->Address[2], pAdapterInfo->Address[3], pAdapterInfo->Address[4], pAdapterInfo->Address[5]);
		pAdapterInfo = pAdapterInfo->Next;		// Progress through linked list
	}
	while(pAdapterInfo);						// Terminate if last adapter
}
*/
////////////////////////////////////////
#define MAX_LOADSTRING 100

//for debug
#if USE_LOG
static FILE* s_LogFile = NULL;
#define LOG_FILE	"HungTrung_%li.log"
static char s_LogFileName[64];
#endif 
struct WorkSpace{
	bool isToolbar;
	int ToolbarHeight;
};
WorkSpace _workspace = {false,100};
void PrintLog(const char* format, ...)
{
#if USE_LOG

	if (s_LogFile == NULL)
	{
		GX_MEMSET(s_LogFileName, 0, 64);
		SPRINTF( s_LogFileName, LOG_FILE, time(NULL) );
		fopen_s(&s_LogFile, s_LogFileName, "w");
	}
	
	va_list arg_list;
	va_start(arg_list, format);

	if (s_LogFile != NULL)
	{
		vfprintf(s_LogFile, format, arg_list);
		fprintf("\n");
		fflush(s_LogFile);
	}

	va_end(arg_list);
	
#endif
}




// Global Variables:
TCHAR szTitle[MAX_LOADSTRING];					// The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];			// the main window class name

HINSTANCE		hInst			= NULL;	// current instance
HWND			hMainWnd		= NULL; // main window
HDC				hGameWndDC		= NULL;	// current DC of the main window

int				nAppExit;		// application exit flag
BOOL			bPause			= FALSE;
BOOL			bPlayOneFrame	= FALSE;
BOOL			bConPause		= FALSE;

Simulator*       _simulator		= NULL;
CGame*			g_pGame			= NULL;	
BOOL			LANDSCAPE_ENABLED = false;

//OpenGL var
HGLRC			hRC 			= NULL;		// Permanent Rendering Context
GLfloat			aspectRatio 	= 1.0f;
BOOL			bLockDisplay	= FALSE;	// to be thread safe

//OpenGL function
int InitGL(GLvoid);
GLvoid CloseGL(GLvoid);
void Refresh3D();

// music 
DWORD chan;
HWND win=NULL;

//sound
#define CORE_GAME_MAX_SOUND		50
DWORD chan_sound[CORE_GAME_MAX_SOUND];

//game control function
void GamePause()
{
	bPause = TRUE;
}

void GameResume()
{
	bPause = FALSE;
	bPlayOneFrame = FALSE;
	bConPause = FALSE;
}

void PauseScreen()
{
	TextOutA( hGameWndDC, 10, 10, "Game Pause! F6 resume.", 22 );	
}

void PCDisplayUpdate(HDC hdc)
{
	if (bLockDisplay)
	{
		return;
	}
	
	bLockDisplay = TRUE;
	SwapBuffers(hGameWndDC);

	bLockDisplay = FALSE;
}


unsigned int GetTime()
{
	return GetTickCount();
}

void MainUpdate()
{
	if(bPause)
	{
		PauseScreen();
		return;
	}
	if ((!bPause || bPlayOneFrame) && !bConPause)
	{
		//Refresh3D();			
		bPlayOneFrame = FALSE;
		//process system event
		if(g_pGame->_e._is_call_system){
			//printf("engine call\n");
			g_pGame->_e._is_call_system = false;
			int event_pointer = 0;
			CEvent* evt = g_pGame->_e.getEventOfClass(&event_pointer,EVENT_CLASS_ENGINE);
			while(evt){
				switch(evt->_id){
				case ECODE_SUBMIT_ACHI:
					{
						int achi_id = *evt->_data;
					}break;
				case ECODE_TEXT_INPUT_SHOW:
					{
						SIMULATOR->openContainer();
						SIMULATOR->setInputText(evt->_data,evt->_data_len);
					}
					break;
				}
				evt->_state = EVENT_STATE_DEATH;
				evt = g_pGame->_e.getEventOfClass(&event_pointer,EVENT_CLASS_ENGINE);
			}
		}
		g_pGame->Run();
	}

	if (g_pGame->_isExit)
	{
		nAppExit = 1;
	}

	// draw screen to window
	if (!bConPause)
	{
		PCDisplayUpdate(hGameWndDC);
	}
}



// Forward declarations of functions included in this code module:
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
	//create console to debug
	AllocConsole();
	freopen("con","w",stdout);
	freopen("con","w",stderr);

	_simulator = Simulator::getInstance(SIMULATOR_SCR_W,SIMULATOR_SCR_H,SIMULATOR_SCR_SCALE,SIMULATOR_MAX_FPS);
	
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

 	// TODO: Place code here.
	MSG msg;
	HACCEL hAccelTable;


	// Initialize global strings
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_IPHONEGAME, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	// Perform application initialization:
	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_IPHONEGAME));
	//init device
	CDevice device;
	device.SCR_W = _simulator->Width;
	device.SCR_H = _simulator->Height;
	device.Design_Orientation = SIMULATOR_DESIGN_ORIENTATION;
	device.Orientation =  (_simulator->Width>_simulator->Height)?ORIENTATION_LANDSCAPE_270:ORIENTATION_PORTRAIT;
	device.DeviceID = SIMULATOR_DEVICE_ID;
	device.DeviceName = SIMULATOR_DEVICE_ID;
	
	g_pGame = new CGame(device);
	g_pGame->Init();
	g_pGame->_g->SetViewPort(_simulator->Width*_simulator->ScrScale,_simulator->Height*_simulator->ScrScale);
	nAppExit = 0;

	// Main message loop:
	while (!nAppExit)
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
			{
				if (msg.message == WM_QUIT)
				{
					nAppExit = 1;
					break;
				}
				else
				{
					TranslateMessage(&msg);
					DispatchMessage(&msg);
				}
			}
		}
		else
		{
			MainUpdate();
		}
	}
	g_pGame->Release();
	SAFE_DEL(g_pGame);
	
	while (bLockDisplay);
	bLockDisplay = TRUE;
	
	CloseGL();
	
	ReleaseDC(hMainWnd, hGameWndDC);
	hGameWndDC = NULL;
	DestroyWindow(hMainWnd);
	hMainWnd = NULL;
	
	if (!UnregisterClass( szWindowClass, hInstance ))
	{
		MessageBox(NULL, L"Could Not Unregister Class.", L"SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
	}

	InvalidateRect(NULL, NULL, TRUE);

	return (int) msg.wParam;
}



//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
//  COMMENTS:
//
//    This function and its usage are only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_IPHONEGAME));
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= NULL;//MAKEINTRESOURCE(IDC_IPHONEGAME);
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

	return RegisterClassEx(&wcex);
}

//
//   FUNCTION: InitInstance(HINSTANCE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
	hInst = hInstance; // Store instance handle in our global variable
	int real_w = _simulator->Width * _simulator->ScrScale;
	int real_h = _simulator->Height * _simulator->ScrScale;
	if(_workspace.isToolbar) real_h += _workspace.ToolbarHeight;

	hMainWnd = CreateWindowEx(WS_EX_APPWINDOW| WS_EX_WINDOWEDGE,
								szWindowClass,
								szTitle,
								WS_VISIBLE|WS_SYSMENU|WS_BORDER|WS_CLIPCHILDREN, 
								//WS_BORDER|WS_CLIPCHILDREN,
								CW_USEDEFAULT,CW_USEDEFAULT,
								real_w + GetSystemMetrics(SM_CXDLGFRAME) * 2,
								real_h + 
											GetSystemMetrics(SM_CYCAPTION) +
											//GetSystemMetrics(SM_CYMENU) +
											GetSystemMetrics(SM_CXDLGFRAME) * 2,
								NULL,NULL,hInst,NULL); 

	if (!hMainWnd)
	{
		return FALSE;
	}
   
	//OpenGL
	GLuint		PixelFormat;

	hGameWndDC = GetDC(hMainWnd);

	static	PIXELFORMATDESCRIPTOR pfd =				// pfd Tells Windows How We Want Things To Be
	{
		sizeof(PIXELFORMATDESCRIPTOR),				// Size Of This Pixel Format Descriptor
		1,											// Version Number
		PFD_DRAW_TO_WINDOW |						// Format Must Support Window
		PFD_SUPPORT_OPENGL |						// Format Must Support OpenGL
		PFD_DOUBLEBUFFER,							// Must Support Double Buffering
		PFD_TYPE_RGBA,								// Request An RGBA Format
		16,											// Select Our Color Depth
		0, 0, 0, 0, 0, 0,							// Color Bits Ignored
		0,											// No Alpha Buffer
		0,											// Shift Bit Ignored
		0,											// No Accumulation Buffer
		0, 0, 0, 0,									// Accumulation Bits Ignored
		16,											// 16Bit Z-Buffer (Depth Buffer)  
		0,											// No Stencil Buffer
		0,											// No Auxiliary Buffer
		PFD_MAIN_PLANE,								// Main Drawing Layer
		0,											// Reserved
		0, 0, 0										// Layer Masks Ignored
	};	
	
	PixelFormat = ChoosePixelFormat(hGameWndDC, &pfd);
	
	SetPixelFormat(hGameWndDC, PixelFormat, &pfd);
	hRC = wglCreateContext(hGameWndDC);
	wglMakeCurrent(hGameWndDC, hRC);
	InitGL();

	ShowWindow(hMainWnd, nCmdShow);
	UpdateWindow(hMainWnd);

	return TRUE;
}

//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND	- process the application menu
//  WM_PAINT	- Paint the main window
//  WM_DESTROY	- post a quit message and return
//
//

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	int x,y;
	//unsigned long time;
	//POINT mp;

	switch (message) 
	{
		case WM_COMMAND:
			wmId    = LOWORD(wParam); 
			wmEvent = HIWORD(wParam); 
			// Parse the menu selections:
			switch (wmId)
			{
				case IDM_ABOUT:
					DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
					break;

				case IDM_EXIT:
					DestroyWindow(hWnd);
					break;


				default:
					return DefWindowProc(hWnd, message, wParam, lParam);
			}
			break;
		
		case WM_CHAR:
			
			return 0;			
		
		case WM_KEYDOWN:

			// Pause ON/OFF	
			if ((wParam & 0xFF) == VK_SPACE)
				bPause = !bPause;

			// Play one frame (works in paused mode)...
			if ((wParam & 0xFF) == VK_TAB)
				bPlayOneFrame = TRUE;

			// ConsolePause ON/OFF	
			if ((wParam & 0xFF) == VK_PAUSE)
				bConPause = !bConPause;
			
			if ((wParam & 0xFF) == VK_F1)
			{
				LANDSCAPE_ENABLED = !LANDSCAPE_ENABLED;

				int normalWidth = GAME_DESIGN_WIDTH;
				int normalHeight = GAME_DESIGN_HEIGHT;

				int addedWidth = GetSystemMetrics(SM_CXFIXEDFRAME) * 2 + GetSystemMetrics(SM_CXBORDER) * 2;
				int addedHeight = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CYFIXEDFRAME) * 2 + GetSystemMetrics(SM_CXBORDER) * 2;

				if (LANDSCAPE_ENABLED)
				{
					SetWindowPos(hWnd, NULL,0,0, normalHeight + addedWidth, normalWidth + addedHeight, SWP_NOMOVE);
				}
				else
				{
					SetWindowPos(hWnd, NULL,0,0, normalWidth + addedWidth, normalHeight + addedHeight, SWP_NOMOVE);
				}
			}
			else if ((wParam & 0xFF) == VK_F5)
			{
				GamePause();
			}
			else if ((wParam & 0xFF) == VK_F6)
			{
				GameResume();
			}
			else if((wParam & 0xFF) == VK_UP)
			{
				int keysrc = KEY_NARROW_UP;
				g_pGame->_e.put(ECODE_KEY_PRESS,(const char*)&keysrc,4);
			}
			else if((wParam  & 0xFF) == VK_DOWN)
			{
				int keysrc = KEY_NARROW_DOWN;
				g_pGame->_e.put(ECODE_KEY_PRESS,(const char*)&keysrc,4);
			}
			else if((wParam  & 0xFF) == VK_LEFT)
			{
				int keysrc = KEY_NARROW_LEFT;
				g_pGame->_e.put(ECODE_KEY_PRESS,(const char*)&keysrc,4);
			}
			else if((wParam  & 0xFF) == VK_RIGHT)
			{
				int keysrc = KEY_NARROW_RIGHT;
				g_pGame->_e.put(ECODE_KEY_PRESS,(const char*)&keysrc,4);
			}
			else if((wParam  & 0xFF) == VK_BACK)
			{
				int keysrc = KEY_BACK;
				g_pGame->_e.put(ECODE_KEY_PRESS,(const char*)&keysrc,4);
			}
			else if((wParam  & 0xFF) == VK_HOME)
			{
				int keysrc = KEY_HOME;
				g_pGame->_e.put(ECODE_KEY_PRESS,(const char*)&keysrc,4);
			}else if((wParam  & 0xFF) == 'g' || (wParam  & 0xFF) == 'G')
			{
				int keysrc = KEY_GAME_G;
				g_pGame->_e.put(ECODE_KEY_PRESS,(const char*)&keysrc,4);
				
			}else if((wParam  & 0xFF) == 'v' || (wParam  & 0xFF) == 'V')
			{
				int keysrc = KEY_GAME_V;
				g_pGame->_e.put(ECODE_KEY_PRESS,(const char*)&keysrc,4);
			}else if((wParam  & 0xFF) == 'n' || (wParam  & 0xFF) == 'N')
			{
				int keysrc = KEY_GAME_N;
				g_pGame->_e.put(ECODE_KEY_PRESS,(const char*)&keysrc,4);
			}
			break;

		case WM_KEYUP:
			if (g_pGame)
			{
				if (wParam == VK_DIVIDE)
				{
					//g_pGame->pSoundManager->SetMasterVolume(0);
				}
				if((wParam & 0xFF) == VK_UP)
				{
					int keysrc = KEY_NARROW_UP;
					g_pGame->_e.put(ECODE_KEY_RELEASE,(const char*)&keysrc,4);
				}
				else if((wParam  & 0xFF) == VK_DOWN)
				{
					int keysrc = KEY_NARROW_DOWN;
					g_pGame->_e.put(ECODE_KEY_RELEASE,(const char*)&keysrc,4);
				}
				else if((wParam  & 0xFF) == VK_LEFT)
				{
					int keysrc = KEY_NARROW_LEFT;
					g_pGame->_e.put(ECODE_KEY_RELEASE,(const char*)&keysrc,4);
				}
				else if((wParam  & 0xFF) == VK_RIGHT)
				{
					int keysrc = KEY_NARROW_RIGHT;
					g_pGame->_e.put(ECODE_KEY_RELEASE,(const char*)&keysrc,4);
				}
				else if((wParam  & 0xFF) == VK_BACK)
				{
					int keysrc = KEY_BACK;
					g_pGame->_e.put(ECODE_KEY_RELEASE,(const char*)&keysrc,4);
				}
				else if((wParam  & 0xFF) == VK_HOME)
				{
					int keysrc = KEY_HOME;
					g_pGame->_e.put(ECODE_KEY_RELEASE,(const char*)&keysrc,4);
				}else if((wParam  & 0xFF) == 'g' || (wParam  & 0xFF) == 'G')
				{
					int keysrc = KEY_GAME_G;
					g_pGame->_e.put(ECODE_KEY_RELEASE,(const char*)&keysrc,4);
				}else if((wParam  & 0xFF) == 'v' || (wParam  & 0xFF) == 'V')
				{
					int keysrc = KEY_GAME_V;
					g_pGame->_e.put(ECODE_KEY_RELEASE,(const char*)&keysrc,4);
				}else if((wParam  & 0xFF) == 'n' || (wParam  & 0xFF) == 'N')
				{
					int keysrc = KEY_GAME_N;
					g_pGame->_e.put(ECODE_KEY_RELEASE,(const char*)&keysrc,4);
				}
			}
			break;

		case WM_SIZE:
			return 0;

		case WM_LBUTTONDOWN:
			
			x = LOWORD(lParam);
			y = HIWORD(lParam);
			if(_workspace.isToolbar) y -= _workspace.ToolbarHeight;
			if(y < 0){
			}else{
				_simulator->correctTouch(&x,&y);
				//4B - touch system
				g_pGame->_touch_id_gen++;
				g_pGame->NotifyTouchesBegan(g_pGame->_touch_id_gen, x, y, 1);
				//4B - end
			}
			break;

		case WM_LBUTTONUP:

			//4B - touch system
			x = LOWORD(lParam);
			y = HIWORD(lParam);
			if(_workspace.isToolbar) y -= _workspace.ToolbarHeight;
			if(y < 0){
			}else{
				_simulator->correctTouch(&x,&y);
				g_pGame->NotifyTouchesEnd(g_pGame->_touch_id_gen, x, y, 1);
			}
			//4B - end

			break;

		case WM_MOUSEMOVE:
			//4B - touch system
			if(wParam == MK_LBUTTON)
			{				
				x = LOWORD(lParam);
				y = HIWORD(lParam);
				if(_workspace.isToolbar) y -= _workspace.ToolbarHeight;
				if(y < 0){
				}else{
					_simulator->correctTouch(&x,&y);
					g_pGame->NotifyTouchesMoved(g_pGame->_touch_id_gen, x, y, 1);
				}
			}
			//4B - end

			{
				int xx = LOWORD(lParam);
				int yy = HIWORD(lParam);
				if(_workspace.isToolbar) y -= _workspace.ToolbarHeight;
				if(yy < 0){
				}else{
					_simulator->correctTouch(&xx,&yy);
					char txt[20];
					sprintf(txt, "x: %d   y: %d", xx, yy);
					SetWindowTextA(hWnd, txt);
				}
			}
			break;
		case WM_CREATE:
			{
				printf("WM_CREATE called\n");
				//HWND hwnd = 
				win=hWnd;
				// initialize BASS
				if (!BASS_Init(-1,44100,0,hWnd,NULL)) {
					printf("Can't initialize sound device\n");
				}
				_simulator->initContainer(hWnd,((LPCREATESTRUCT)lParam)->hInstance,szWindowClass);
				//create a text input
				//HWND hwnd_edit = CreateWindow(TEXT("edit"),NULL,WS_CHILD|WS_VISIBLE|WS_BORDER|ES_LEFT|ES_AUTOHSCROLL,0,0,100,20,win,(HMENU)100,((LPCREATESTRUCT)lParam)->hInstance,NULL);
			}
			break;
		case WM_ACTIVATE:

			if (LOWORD(wParam) == WA_INACTIVE)
			{
				
			}

			break;

		case WM_DESTROY:
			PostQuitMessage(0);
			break;

		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
	}

	return 0;
}

// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	UNREFERENCED_PARAMETER(lParam);
	switch (message)
	{
	case WM_INITDIALOG:
		return (INT_PTR)TRUE;

	case WM_COMMAND:
		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
		{
			EndDialog(hDlg, LOWORD(wParam));
			return (INT_PTR)TRUE;
		}
		break;
	}
	return (INT_PTR)FALSE;
}


//void LinkOES2EXT();

int InitGL(GLvoid)										
{
	//LinkOES2EXT ();
	::glShadeModel(GL_SMOOTH);							// Enable Smooth Shading
	::glClearColor(0.0f, 0.0f, 0.0f, 0.0f);				// Black Background
	::glClearDepth(1.0f);									// Depth Buffer Setup
	::glEnable(GL_DEPTH_TEST);							// Enables Depth Testing
	::glDepthFunc(GL_LEQUAL);								// The Type Of Depth Testing To Do
	::glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);	// Really (NOT) Nice Perspective Calculations
	return TRUE;										// Initialization Went OK
}	


void Refresh3D()
{
	::glEnable(GL_DEPTH_TEST);
	::glDepthMask(TRUE);		
	::glDepthFunc(GL_LEQUAL);
	::glClearDepth(1.0f);
	::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		
}

GLvoid CloseGL(GLvoid)								
{
	if (hRC)	
	{
		wglMakeCurrent(NULL, NULL);
		wglDeleteContext(hRC);
		hRC=NULL;				
	}
}

unsigned long OS_GetTime(void)
{
	return clock();
}

bool SaveAppData(const char* filename, const char* data_to_save, int data_length, bool is_append)
{
	FILE* stream = NULL;

	if (is_append)
	{
		stream = fopen(filename, "ab");
	}
	else
	{
		stream = fopen(filename, "wb");
	}

	if (stream != NULL)
	{
		fwrite(data_to_save, sizeof(BYTE), data_length, stream);
	}
	else
	{
		return false;
	}

	fclose(stream);
	
	return true;
}

int ReadAppData(const char* filename, char*& readed_data)
{
	FILE* stream = NULL;

	stream = fopen(filename, "rb");

	if (stream != NULL)
	{
		fseek(stream, 0, SEEK_END);
		int size = ftell(stream);
		fseek(stream, 0, SEEK_SET);

		readed_data = new char[size];

		fread(readed_data, sizeof(char), size, stream);
		
		fclose(stream);

		return size;
	}

	return 0;
}

extern "C" Bytes* ReadFileToBytes(const char* filename){
	FILE* stream = NULL;
	stream = fopen(filename, "rb");
	if (stream != NULL)
	{
		fseek(stream, 0, SEEK_END);
		int size = ftell(stream);
		fseek(stream, 0, SEEK_SET);

		Bytes* readed_data = new Bytes();
		readed_data->_data_len = size;
		readed_data->_data = new char[size];
		fread(readed_data->_data, sizeof(char), size, stream);
		
		fclose(stream);

		return readed_data;
	}

	return NULL;
}

bool DeleteAppData(const char* filename)
{	
	if (remove(filename) != 0)
	{
		return false;
	}
		
	return true;
}

extern "C" void SaveImageToPhotosAlbum(BYTE* img_data, int img_data_len)
{
}

extern "C" void OS_LoadMusic(const char* filename)
{
	if (!(chan=BASS_StreamCreateFile(FALSE,filename,0,0,BASS_SAMPLE_LOOP))
		&& !(chan=BASS_MusicLoad(FALSE,filename,0,0,BASS_MUSIC_RAMP|BASS_SAMPLE_LOOP,0))) {
		printf("Can't load file\n");
	}
}

extern "C" void OS_PlayCurrentMusic(int num_loop)
{
	BASS_ChannelPlay(chan,FALSE);
}

extern "C" void OS_PlayLibMusic(int num_loop)
{
	
}

extern "C" void OS_StopLibMusic()
{
	
}

extern "C" void OS_PauseLibMusic()
{
	
}

extern "C" void OS_UpdateLibSongList()
{
	
}

extern "C" int OS_GetLibSongNum()
{
	return 0;
}

extern "C" char* OS_GetLibSongTitle(int index)
{
	return "song title";
}

extern "C" char* OS_GetLibCurrentSongTitle()
{
	return "song title";
}

extern "C" double OS_GetLibSongTime()
{
	return 0;
}

extern "C" double OS_GetCurrentLibMusicTime()
{
	return 0;
}

extern "C" void OS_StopCurrentMusic()
{
	BASS_ChannelStop(chan);
}

extern "C" void OS_PauseCurrentMusic()
{
	BASS_ChannelPause(chan);
}

extern "C" void OS_PreviousMusic(int numSecond)
{
	long pos = BASS_ChannelGetPosition(chan,BASS_POS_BYTE); // position in bytes
	double elapsedtime = BASS_ChannelBytes2Seconds(chan, pos); // the elapsed time length
	elapsedtime-=numSecond;
	pos=BASS_ChannelSeconds2Bytes(chan,elapsedtime);
	BASS_ChannelSetPosition( chan,  pos,  BASS_POS_BYTE);
}

extern "C" void OS_ForwardMusic(int numSecond)
{
	long pos = BASS_ChannelGetPosition(chan,BASS_POS_BYTE); // position in bytes
	double elapsedtime = BASS_ChannelBytes2Seconds(chan, pos); // the elapsed time length
	elapsedtime+=numSecond;
	pos=BASS_ChannelSeconds2Bytes(chan,elapsedtime);
	BASS_ChannelSetPosition( chan,  pos,  BASS_POS_BYTE);
}

extern "C" double OS_GetCurrentMusicTime()
{
	long pos = BASS_ChannelGetPosition(chan,BASS_POS_BYTE); // position in bytes
	double elapsedtime = BASS_ChannelBytes2Seconds(chan, pos); // the elapsed time length
	return elapsedtime;
}

extern "C" double OS_GetSongTime()
{
	long _length=BASS_ChannelGetLength(chan,BASS_POS_BYTE);
	double song_time = BASS_ChannelBytes2Seconds(chan, _length); // the elapsed time length
	return song_time;
}

extern "C" bool OS_IsCurrentMusicPlaying()
{
	return false;
}

extern "C" void OS_LoadSFX(const char* filename, int sound_id)
{
	sound_id %= CORE_GAME_MAX_SOUND;
	printf("load sound:%d %s\n",sound_id,filename);
	if (!(chan_sound[sound_id]=BASS_StreamCreateFile(FALSE,filename,0,0,0))
		&& !(chan_sound[sound_id]=BASS_MusicLoad(FALSE,filename,0,0,BASS_MUSIC_RAMP,0))) {
		printf("Can't load file\n");
	}
}

extern "C" void OS_PlaySFX(int sound_id)
{
	sound_id %= CORE_GAME_MAX_SOUND;
	BASS_ChannelPlay(chan_sound[sound_id], TRUE);
}

extern "C" void OS_StopAllSFX()
{
	for (int i = 0; i < CORE_GAME_MAX_SOUND; i++)
	{
		BASS_ChannelStop(chan_sound[i]);
	}
}

extern "C" void ShowPicker()
{
}

extern "C" bool MediaPickerIsDone()
{
	return true;
}

extern "C" void PublishingFacebookFeedStories(int new_score)
{
}

extern "C" void ShowFBConnectDialog()
{
}

extern "C" void ShowFBConnectButton(int x, int y)
{
}

extern "C" void HideFBConnectButton()
{
}

extern "C" void ShowTWConnectDialog()
{
}

extern "C" void ShowTWConnectButton(int x, int y)
{
}

extern "C" bool TWLoginIsDone()
{
	return true;
}

extern "C" void HideTWConnectButton()
{
}

extern "C" void PublishTWStream(const char* string)
{

}

extern "C" int GetDeviceModel()
{
	return 0;//DEVICE_SIMULATOR;
}

extern "C" int GetPhoneRotSpeedLeftRight(int phoneOrientation)
{
	return 0;
}

extern "C" int GetPhoneRotSpeedFwdBack(int phoneOrientation)
{
	return 0;
}

extern "C" void showGCLeaderBoard(){}

extern "C" void showGCAchievementBoard(){}

// game center function
extern "C" void InitGCBoard(){}
extern "C" bool IsUsingGC()
{
	return true;
}
extern "C" bool isGCAvailable()
{
	return false;
}
extern "C" void SubmitScore(int score, const char* category_id){}
extern "C" void SubmitAchievement(const char* identifier, int percentComplete){}
extern "C" void ShowCTBoard(){}
extern "C" void InitCT(){}
extern "C" void PublishFBStream(const char* msg){}
extern "C" float GetAccelX()
{
	return 0;
}
extern "C" float GetAccelY()
{
	return 0;
}
extern "C" float GetAccelZ()
{
	return 0;
}
extern "C" void ShowRateDialog(){}
#if defined(USE_OPENFEINT)
extern "C" void InitOpenFeint(char* displayName){}
extern "C" void LaunchOFDashboard(){}
extern "C" void LaunchOFAchievementBoard(){}
extern "C" void LaunchOFLeaderBoard(char* leaderboardId){}
extern "C" void SubmitOfAchievement(const char* achievementId){}
extern "C" void SubmitOFScore(int score, const char* leaderboardId)
{
//	g_pGame->_submitScoreComplete = true;
}
extern "C" void PublishOFSocialNotification(const char* message, const char* imageName){}
extern "C" int GetInterfaceVersion()
{
	return 0;
}
#endif